package util;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;

import javax.swing.AbstractListModel;
import javax.swing.MutableComboBoxModel;
import javax.swing.event.ListDataListener;

import com.google.common.base.Objects;
import com.google.common.collect.AbstractIterator;


public class FowardingComboBoxModel<E> extends AbstractListModel<E> implements
MutableComboBoxModel<E>, List<E> {
    
    
    
    private class Iterator extends AbstractIterator<E> {
        
        int index = 0;
        
        @Override
        protected E computeNext()
        {
            // TODO Auto-generated method stub
            return null;
        }
        
        
    }
    
    private final MutableComboBoxModel<E> undelyingModel;
    private Object selectedItem;
    
    public FowardingComboBoxModel(MutableComboBoxModel<E> undelyingModel)
    {
        this.undelyingModel = undelyingModel;
    }
    
    
    
    @Override
    public void setSelectedItem(Object anItem)
    {
        if( !Objects.equal(anItem, selectedItem)) {
            selectedItem = anItem;
            fireContentsChanged(this, -1, -1);
        }
    }
    
    @Override
    public Object getSelectedItem()
    {
        return selectedItem;
    }
    
    @Override
    public int getSize()
    {
        return undelyingModel.getSize();
    }
    
    @Override
    public E getElementAt(int index)
    {
        return undelyingModel.getElementAt(index);
    }
    
    @Override
    public void addListDataListener(ListDataListener l)
    {
        super.addListDataListener(l);
        undelyingModel.addListDataListener(l);
    }
    
    @Override
    public void removeListDataListener(ListDataListener l)
    {
        super.removeListDataListener(l);
        undelyingModel.removeListDataListener(l);
    }
    
    @Override
    public void addElement(E item)
    {
        undelyingModel.addElement(item);
    }
    
    @Override
    public void removeElement(Object obj)
    {
        undelyingModel.removeElement(obj);
    }
    
    @Override
    public void insertElementAt(E item, int index)
    {
        undelyingModel.insertElementAt(item, index);
    }
    
    @Override
    public void removeElementAt(int index)
    {
        undelyingModel.removeElementAt(index);
    }
    
    
    
    @Override
    public int size()
    {
        return getSize();
    }
    
    
    
    @Override
    public boolean isEmpty()
    {
        return size() == 0;
    }
    
    
    
    @Override
    public boolean contains(Object o)
    {
        // TODO Auto-generated method stub
        return false;
    }
    
    @Override
    public Object[] toArray()
    {
        Object[] ar = new Object[size()];
        for(int i = 0; i < size(); i++) {
            ar[i] = get(i);
        }
        return ar;
    }
    
    
    
    @Override
    public <T> T[] toArray(T[] a)
    {
        if(a.length < size()) {
            a = (T[]) Array.newInstance(a.getClass().getComponentType(), size());
        }
        for(int i = 0; i < size(); i++) {
            a[i] = (T) get(i);
        }
        return a;
    }
    
    
    
    @Override
    public boolean add(E e)
    {
        int oldSize = size();
        addElement(e);
        return size() > oldSize;
    }
    
    
    
    @Override
    public boolean remove(Object o)
    {
        int oldSize = size();
        removeElement(o);
        return size() < oldSize;
    }
    
    
    
    @Override
    public boolean containsAll(Collection<?> c)
    {
        boolean contains = true;
        for(Object o : c) {
            contains &= contains(o);
        }
        return contains;
    }
    
    @Override
    public boolean addAll(Collection<? extends E> c)
    {
        boolean changed = false;
        for(E e : c) {
            changed |= add(e);
        }
        return changed;
    }
    
    
    
    @Override
    public boolean addAll(int index, Collection<? extends E> c)
    {
        boolean changed = false;
        for(E e : c) {
            int oldSize = size();
            add(index, e);
            changed |= size() > oldSize;
            index++;
        }
        return changed;
    }
    
    
    
    @Override
    public boolean removeAll(Collection<?> c)
    {
        boolean changed = false;
        for(Object o : c) {
            changed |= remove(o);
        }
        return changed;
    }
    
    
    
    @Override
    public boolean retainAll(Collection<?> c)
    {
        boolean changed = false;
        for(E e : this) {
            if( !c.contains(e)) {
                changed |= remove(e);
            }
        }
        return changed;
    }
    
    
    
    @Override
    public void clear()
    {
        for(int i = 0; i < getSize(); i++) {
            removeElementAt(i);
        }
    }
    
    
    
    @Override
    public E get(int index)
    {
        return getElementAt(index);
    }
    
    
    
    @Override
    public E set(int index, E element)
    {
        insertElementAt(element, index);
        E removed = getElementAt(index + 1);
        removeElementAt(index + 1);
        return removed;
    }
    
    
    
    @Override
    public void add(int index, E element)
    {
        insertElementAt(element, index);
    }
    
    
    
    @Override
    public E remove(int index)
    {
        E removed = getElementAt(index);
        removeElementAt(index);
        return removed;
    }
    
    
    
    @Override
    public int indexOf(Object o)
    {
        // TODO Auto-generated method stub
        return 0;
    }
    
    
    
    @Override
    public int lastIndexOf(Object o)
    {
        // TODO Auto-generated method stub
        return 0;
    }
    
    
    
    @Override
    public ListIterator<E> listIterator()
    {
        // TODO Auto-generated method stub
        return null;
    }
    
    
    
    @Override
    public ListIterator<E> listIterator(int index)
    {
        // TODO Auto-generated method stub
        return null;
    }
    
    
    
    @Override
    public List<E> subList(int fromIndex, int toIndex)
    {
        // TODO Auto-generated method stub
        return null;
    }
    
    
    
    @Override
    public Iterator iterator()
    {
        // TODO Auto-generated method stub
        return null;
    }
}
